package com.pubinfo.passbook.data.service.impl;

import cn.hutool.core.date.DateUtil;
import com.pubinfo.passbook.common.config.FtpUploadConfig;
import com.pubinfo.passbook.common.entity.*;
import com.pubinfo.passbook.common.model.bo.uccp.ShortMessageParam;
import com.pubinfo.passbook.common.service.dubbo.DubboService;
import com.pubinfo.passbook.common.service.master.*;
import com.pubinfo.passbook.common.utils.EncryptUtil;
import com.pubinfo.passbook.common.utils.FtpTool;
import com.pubinfo.passbook.data.service.FtpService;
import com.pubinfo.passbook.data.service.TFileInfoService;
import com.pubinfo.passbook.data.service.TFtpPasswordService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.xml.bind.DatatypeConverter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class FtpServiceImpl implements FtpService {
  
  @Autowired
  TFileInfoService tFileInfoService;
  @Value("${file.uploadFolder}")
  private String filePath;
  @Autowired
  TFileOpenFtpService openFtpService;
  @Autowired
  ITFileFtpService fileFtpService;
  @Autowired
  ITFileElectronicFtpService fileElectronicFtpService;
  
  @Autowired
  ITFileEnclosureFtpService fileEnclosureFtpService;
  
  @Resource
  FtpUploadConfig config;

  @Autowired
  TFtpPasswordService tFtpPasswordService;
  @Autowired
  DubboService vatService;

  @Autowired
  TFileOpenEnclosureFtpService tFileOpenEnclosureFtpService;

  @Autowired
  TFileOpenElectronicFtpService tFileOpenElectronicFtpService;


  @Override
  @SneakyThrows
  public TFileOpenEnclosureFtp uploadOpenEnclosureFile(TFileInfo fileInfo){
    String workPath = createWorkPath(fileInfo, config.getEnclosure().getWorkpath());
    if (FtpTool.upload(config.getEnclosure().getIp(), config.getEnclosure().getPort(), config.getEnclosure().getUsername(), config.getEnclosure().getPassword(), workPath, new FileInputStream(fileInfo.getPath()), fileInfo.getName())) {
      TFileOpenEnclosureFtp tFileOpenEnclosureFtp = new TFileOpenEnclosureFtp();
      tFileOpenEnclosureFtp.setName(fileInfo.getName());
      tFileOpenEnclosureFtp.setHttp(createHTTP(fileInfo, workPath));
      tFileOpenEnclosureFtp.setFtp(workPath);
      tFileOpenEnclosureFtp.setFileId(fileInfo.getId());
      tFileOpenEnclosureFtpService.save(tFileOpenEnclosureFtp);
      return tFileOpenEnclosureFtp;
    }
    return null;
  }

  @Override
  @SneakyThrows
  public TFileOpenElectronicFtp uploadOpenElectronicFile(TFileInfo fileInfo) {
    String workPath = createWorkPath(fileInfo, config.getElectronic().getWorkpath());
    if (FtpTool.upload(config.getElectronic().getIp(), config.getElectronic().getPort(), config.getElectronic().getUsername(), tFtpPasswordService.getPassword(), workPath, new FileInputStream(fileInfo.getPath()), fileInfo.getName())) {
      TFileOpenElectronicFtp tFileOpenElectronicFtp = new TFileOpenElectronicFtp();
      tFileOpenElectronicFtp.setName(fileInfo.getName());
      tFileOpenElectronicFtp.setFileRelativePath(workPath);
      tFileOpenElectronicFtp.setFtp(workPath + "/" + fileInfo.getName());
      tFileOpenElectronicFtp.setFileId(fileInfo.getId());
      tFileOpenElectronicFtp.setMd5Code(MD5(fileInfo.getPath()));
      tFileOpenElectronicFtpService.save(tFileOpenElectronicFtp);
      return tFileOpenElectronicFtp;
    }
    return null;
  }

  @Override
  @SneakyThrows
  public List<TFileOpenEnclosureFtp> uploadOpenEnclosureFile(List<TFileInfo> fileInfos) {
    if (CollectionUtils.isEmpty(fileInfos)) {
      return null;
    }
    List<TFileOpenEnclosureFtp> urlList = new ArrayList<>();
    for (TFileInfo info : fileInfos) {
      urlList.add(uploadOpenEnclosureFile(info));
    }
    return urlList;
  }

  @Override
  @SneakyThrows
  public List<TFileOpenElectronicFtp> uploadOpenElectronicFile(List<TFileInfo> fileInfos) {
    if (CollectionUtils.isEmpty(fileInfos)) {
      return null;
    }
    List<TFileOpenElectronicFtp> urlList = new ArrayList<>();
    for (TFileInfo info : fileInfos) {
      urlList.add(uploadOpenElectronicFile(info));
    }
    return urlList;
  }


  @Override
  @SneakyThrows
  public Boolean uploadEnclosure(String id) throws IOException {
    TFileInfo fileInfo = tFileInfoService.getById(id);
    String workPath = createWorkPath(fileInfo, config.getEnclosure().getWorkpath());
    if (FtpTool.upload(config.getEnclosure().getIp(), config.getEnclosure().getPort(), config.getEnclosure().getUsername(), config.getEnclosure().getPassword(), workPath, new FileInputStream(fileInfo.getPath()), fileInfo.getName())) {
      TFileEnclosureFtp tFileEnclosureFtp = new TFileEnclosureFtp();
      tFileEnclosureFtp.setName(fileInfo.getName());
      tFileEnclosureFtp.setHttp(createHTTP(fileInfo, workPath));
      tFileEnclosureFtp.setFtp(workPath);
      tFileEnclosureFtp.setFileId(fileInfo.getId());
      return fileEnclosureFtpService.save(tFileEnclosureFtp);
    }
    return false;
  }

  @Override
  public Boolean uploadElectronic(String id) throws IOException {
    TFileInfo fileInfo = tFileInfoService.getById(id);
    String workPath = createWorkPath(fileInfo, config.getElectronic().getWorkpath());
    if (FtpTool.upload(config.getElectronic().getIp(), config.getElectronic().getPort(), config.getElectronic().getUsername(), tFtpPasswordService.getPassword(), workPath, new FileInputStream(fileInfo.getPath()), fileInfo.getName())) {
      TFileElectronicFtp tFileElectronicFtp = new TFileElectronicFtp();
      tFileElectronicFtp.setName(fileInfo.getName());
      tFileElectronicFtp.setFileRelativePath(workPath);
      tFileElectronicFtp.setFtp(workPath + "/" + fileInfo.getName());
      tFileElectronicFtp.setFileId(fileInfo.getId());
      tFileElectronicFtp.setMd5Code(MD5(fileInfo.getPath()));
      return fileElectronicFtpService.save(tFileElectronicFtp);
    }
    else
    {
      vatService.sendShortMessage(new ShortMessageParam(DateUtil.format(new Date(),"yyyy-MM-dd")+"ftp上传失败请请检查","1867018123"));
    }
    return false;
  }
  
  @Override
  public TFileEnclosureFtp uploadEnclosureFile(String id) throws IOException {
    TFileInfo fileInfo = tFileInfoService.getById(id);
    String workPath = createWorkPath(fileInfo, config.getEnclosure().getWorkpath());
    if (FtpTool.upload(config.getEnclosure().getIp(), config.getEnclosure().getPort(), config.getEnclosure().getUsername(), config.getEnclosure().getPassword(), workPath, new FileInputStream(fileInfo.getPath()), fileInfo.getName())) {
      TFileEnclosureFtp tFileEnclosureFtp = new TFileEnclosureFtp();
      tFileEnclosureFtp.setName(fileInfo.getName());
      tFileEnclosureFtp.setHttp(createHTTP(fileInfo, workPath));
      tFileEnclosureFtp.setFtp(workPath);
      tFileEnclosureFtp.setFileId(fileInfo.getId());
      fileEnclosureFtpService.save(tFileEnclosureFtp);
      return tFileEnclosureFtp;
    }
    return null;
  }
  
  private String createWorkPath(TFileInfo fileInfo, String workpath) {
    return workpath + new SimpleDateFormat("/yyyy/MM/dd/").format(new Date()) + fileInfo.getId() + "/" + fileInfo.getEdition();
  }
  
  //生成工作目录
  private String createHTTP(TFileInfo fileInfo, String workPath) {
    Date date = new Date();
    return "ftp://" + EncryptUtil.encode(config.getEnclosure().getUsername()) +
        ":" + EncryptUtil.encode(config.getEnclosure().getPassword()) +
        "@" + config.getEnclosure().getDomain() + workPath +
        "/" + fileInfo.getName();
  }
  
  private String MD5(String filePath) {
    File file = new File(filePath);
    Long filelength = file.length();
    byte[] filecontent = new byte[filelength.intValue()];
    try {
      FileInputStream in = new FileInputStream(file);
      in.read(filecontent);
      in.close();
      byte[] secretBytes = MessageDigest.getInstance("md5").digest(filecontent);
      return DatatypeConverter.printHexBinary(secretBytes); //将byte数组转为十六进制字符串);
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }
    return null;
  }
}
